package com.santoker.user.service.service.common.impl;

import com.santoker.baseservice.redis.AuthInfo;
import com.santoker.user.service.model.AdminUser;
import com.santoker.user.service.model.User;
import com.santoker.user.service.service.common.RedisService;
import com.santoker.user.service.service.tp.wechat.response.WeChatAppUserInfoResponse;
import com.xiaoleilu.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Redis 操作实现类
 *
 * @author jiangs
 */
@Service
public class RedisServiceImpl implements RedisService {

    private final String AUTH_CODE_PREFIX = "AUTH_CODE_";
    private final String DEFAULT_CODE = "111111";
    private final String USER_LOGIN_KEY_PREFIX = "LOGIN_";
    private final String WX_USER_INFO_KEY_PREFIX = "USER_INFO_";
    private final long USER_LOGIN_KEY_EXPIRE = 60 * 60 * 24 * 30;
    private final long WX_USER_INFO_KEY_EXPIRE = 60 * 60 * 24 * 30;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public long getAuthCodeExpire(String account) {
        String key = genKey(AUTH_CODE_PREFIX, account);
        if (stringRedisTemplate.hasKey(key)) {
            return stringRedisTemplate.opsForValue().getOperations().getExpire(key, TimeUnit.SECONDS);
        }
        return 0;
    }

    @Override
    public void setAuthCode(String account, String code, long timeout) {
        String key = genKey(AUTH_CODE_PREFIX, account);
        set(key, code, timeout);
    }

    @Override
    public boolean verifyCode(String account, String code) {
        if (!DEFAULT_CODE.equals(code)) {
            String captcha = getAuthCode(account);
            return Objects.equals(code, captcha);
        }
        return true;
    }

    @Override
    public void saveToken(User user, String token, String cid, String sid) {
        String key = genKey(USER_LOGIN_KEY_PREFIX, token);
        AuthInfo authInfo = new AuthInfo();
        authInfo.setId(user.getId());
        authInfo.setAccount(user.getAccount());
        authInfo.setMobile(user.getMobile());
        authInfo.setEmail(user.getEmail());
        authInfo.setSId(sid);
        authInfo.setCId(cid);
        authInfo.setToken(token);
        authInfo.setLoginTime(System.currentTimeMillis());
        String val = JSONUtil.toJsonStr(authInfo);
        stringRedisTemplate.opsForValue().set(key,val, USER_LOGIN_KEY_EXPIRE, TimeUnit.SECONDS);
    }

    @Override
    public void removeToken(AuthInfo authInfo) {
        String key = genKey(USER_LOGIN_KEY_PREFIX, authInfo.getToken());
        if (stringRedisTemplate.hasKey(key)) {
            stringRedisTemplate.delete(key);
        }
    }

    @Override
    public void saveAdminToken(AdminUser user, String token, String cid, String sid) {
        String key = genKey(USER_LOGIN_KEY_PREFIX, token);
        AuthInfo authInfo = new AuthInfo();
        authInfo.setId(user.getId());
        authInfo.setAccount(user.getAccount());
        authInfo.setMobile(user.getMobile());
        authInfo.setEmail(user.getEmail());
        authInfo.setSId(sid);
        authInfo.setCId(cid);
        authInfo.setToken(token);
        authInfo.setLoginTime(System.currentTimeMillis());
        String val = JSONUtil.toJsonStr(authInfo);
        stringRedisTemplate.opsForValue().set(key, val, USER_LOGIN_KEY_EXPIRE, TimeUnit.SECONDS);
    }

    @Override
    public void saveWxUserInfo(WeChatAppUserInfoResponse userInfo) {
        String key = genKey(WX_USER_INFO_KEY_PREFIX, userInfo.getOpenid());
        String val = JSONUtil.toJsonStr(userInfo);
        stringRedisTemplate.opsForValue().set(key, val, WX_USER_INFO_KEY_EXPIRE, TimeUnit.SECONDS);
    }

    @Override
    public WeChatAppUserInfoResponse getWxUserInfo(String openid) {
        String key = genKey(WX_USER_INFO_KEY_PREFIX, openid);
        String wxUserInfo = stringRedisTemplate.opsForValue().get(key);
        if (StringUtils.isNotEmpty(wxUserInfo)) {
            WeChatAppUserInfoResponse response = JSONUtil.toBean(wxUserInfo, WeChatAppUserInfoResponse.class);
            return response;
        }
        return null;
    }

    private String getAuthCode(String account) {
        String key = genKey(AUTH_CODE_PREFIX, account);
        return stringRedisTemplate.opsForValue().get(key);
    }

    private String genKey(String prefix, String key) {
        StringBuilder builder = new StringBuilder()
                .append(prefix)
                .append(key);
        return builder.toString();
    }

    private void set(String key, String val, long timeout) {
        stringRedisTemplate.opsForValue().set(key, val, timeout, TimeUnit.SECONDS);
    }

}
